const dbHelper = require('../utils/dbHelper')
const randomHelper = require('../utils/randomHelper')
const { tspLogger } = require('../util')
const { WISE_CAR_BASE_URL } = require('../../config')
// const { TokenManager } = require('../token/index')
const Request = require('../../request')
const sidsHandler = require('./updateSids')

/**
 * 执行控制流程和后期的Tbox上报反向通知车载云
 * @param command 控制指令
 */
async function doControl(command) {
  const { thirdPartyDevId, prodId, sid, data } = command

  const devs = await dbHelper.queryDevs(`thirdPartyDevId = "${thirdPartyDevId}"`)
  if (devs && devs.length !== 1) {
    throw new Error(`t_devices 存在重复 thirdPartyDevId: ${thirdPartyDevId}`)
  }

  // 下发控制
  return callback(devs[0], sid, data)
}

/**
 * 下发控制之后的回调
 *    => 5s 后上报状态到云, 反向通知到华为侧
 */
async function callback(dev, sid, data) {
  // 1. 更新TSP云侧状态
  const code = await updateTsp(dev, sid, data)

  // 2. 20s 后反向通知华为
  setTimeout(() => {
    notifyHW(dev)
  }, 20000)

  // 3. 返回执行结果
  return { code }
}

/**
 * 更新TSP云侧状态
 *   根据sid进行case处理, 方便后面根据不同的sid进行特定的处理
 */
async function updateTsp(dev, sid, data) {
  const { serviceData } = dev
  const handler = sidsHandler[sid]
  if (!handler) {
    tspLogger('error', 'updateTsp', `未找到 sid: ${sid} 对应的handler`)
  }
  const { code, services } = handler(serviceData, sid, data)
  if (code === 0) {
    // 执行成功
    // 写数据库
    await dbHelper.T_DEVICES.update(`serviceData = ${JSON.stringify(services)}`, `thirdPartyDevId = "${dev.thirdPartyDevId}"`)
  }
  return code
}

async function notifyHW(dev) {
  const url = `${WISE_CAR_BASE_URL}/openapi/v1/tsp/notify`

  // const tokenManager = new TokenManager()
  // const token = await tokenManager.app()
  // const reqBody = deviceStatusChangeBuilder(dev)

  // Request.post(url, reqBody, {
  //   Authorization: `Bearer ${token}`
  // }).then(({ data }) => {
  //   console.log('=======================')
  //   console.log(JSON.stringify(data))
  //   console.log('=======================')
  //   return data
  // }).catch(err => {
  //   // handle err
  //   throw new Error(`反向通知车载云失败: ${err}; Error.response: ${err && err.response && JSON.stringify(err.response.data)}. dev: ${JSON.stringify(this.dev)}`)
  // })
}

/**
 * 模拟控车
 * @param command command
 */
function controlCar(command) {
  // do control
}

/**
 * 状态改变构造器
 */
function deviceStatusChangeBuilder(dev) {
  return {
    header: {
      namespace: 'DeviceStatusChanged',
      thirdPartyId: dev.thirdPartyId,
      thirdPartyUserId: dev.thirdPartyUserId,
      messageId: randomHelper.messageId(),
      timestamp: Date.now()
    },
    payload: {
      devices: [{
        thirdPartyDevId: dev.thirdPartyDevId,
        status: dev.status,
        services: dev.services
      }]
    }
  }
}

module.exports = { doControl }
